﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;


using System.Web.Http.Dispatcher;

using System.Collections.Concurrent;
using System.Web.Http.Controllers;
using System.Net.Http;
using System.Globalization;


namespace API
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            
            HttpConfiguration configuration = GlobalConfiguration.Configuration;
            configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

            configuration.Formatters.Add(new Core.MediaTypeFormatter.CommerceMLFormatter());
            configuration.Formatters.Add(new Core.MediaTypeFormatter.MultiFormDataMediaTypeFormatter());

            configuration.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
            configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            configuration.Formatters.Remove(configuration.Formatters.XmlFormatter);

            routes.MapHttpRoute(
                name: "DefaultVersionApi",
                routeTemplate: "api/v{version}/{controller}/{id}",
                defaults: new { version = RouteParameter.Optional, id = RouteParameter.Optional }
            );

            routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional, version = 1 }
            );

            routes.MapHttpRoute(
                name: "DefaultApiExt",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional },
                constraints: new { action = new NotConstraint() }
            );
                
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
      

    public class NotConstraint : IRouteConstraint
    {
        public NotConstraint()
        {

        }

        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            var controllerName = values["controller"].ToString() + "Controller";
            var actionName = values["action"];
            var requestType = httpContext.Request.RequestType;

            var controllers = System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
                .Where(r => typeof(ApiController).IsAssignableFrom(r))
                .Where(r => r.FullName.IndexOf(controllerName) > 0);

            if (controllers.Any())
            {
                if (actionName == null)
                {
                    return controllers.SingleOrDefault().GetMethods().Any(r => r.Name.Equals(requestType, StringComparison.InvariantCultureIgnoreCase));
                }
                else
                {
                    return controllers.SingleOrDefault().GetMethods().Any(r => r.Name.Equals(actionName.ToString(), StringComparison.InvariantCultureIgnoreCase));
                }
            }

            return false;
        }
    }
}